<html>
<head>
<!-- bootStrap CSS -->
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.1/css/bootstrap.min.css" rel="stylesheet">
<!-- JS -->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/1.11.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.1/js/bootstrap.js"></script>
</head>
<body>
<div style="margin-left: 140px;">
 <button type="button" class="btn btn-primary"
     data-toggle="button" οnclick="start()"> 开始
 </button>
 <button type="button" class="btn btn-primary"
     data-toggle="button" οnclick="startEnd()"> 暂停
 </button>
</div>
<div>
<canvas id="myCanvas" width="400" height="600" style="border:5px solid red;">
</canvas>
</div> 
<script type="text/javascript">
//获得画布的对象
var c=document.getElementById("myCanvas");
//表示2维空间
var ctx=c.getContext("2d");
//格子的宽度初始化为10像素
var gridWidth=20;
//定义食物，将多个食物存放在数组中
var foots=new Array();
//定义蛇，多条蛇
var snacks=new Array();
//定义是否移动
var sfmove=true;
//定义初始化方法
function Init(x,y,w){
 var t=this;
 t.x=x;
 t.y=y;
 t.w=w;
 //初始化食物的方法
 t.footInit=function(){
   ctx.fillStyle='red';
   ctx.strokeStyle='white';
   ctx.fillRect(x,y,w,w);
   ctx.strokeRect(x,y,w,w);
 };
 //初始化蛇
 t.snackInit=function(){
  ctx.fillStyle='black';
  ctx.strokeStyle='white';
  ctx.fillRect(x,y,w,w);
  ctx.strokeRect(x,y,w,w);
 };
 //清除蛇尾
 t.clear=function(){
  ctx.fillStyle='white';
  ctx.strokeStyle='white';
  ctx.fillRect(x,y,w,w);
  ctx.strokeRect(x,y,w,w);
 };
 //检查碰撞
 t.check=function(note){
  if(this.x==note.x && this.y==note.y){
   //碰撞了返回true;
   return true;
  }else{
   return false;
  }
 };
 //清除食物
 t.clearFoot=function(){
  ctx.fillStyle='black';
  ctx.strokeStyle='white';
  ctx.fillRect(x,y,w,w);
  ctx.strokeRect(x,y,w,w);
  
 };
 //画游戏结束
 t.gameOver=function(){
  ctx.font="30px Arial";
  ctx.strokeText("GameOver!",x,y);
 };
}
//产生食物的方法
function createFoot(){
 var t=this;
 //设置画布
 
 //随机产生事物
 t.addFont=function(x,y){
 console.log("产生一个点");
  var x=(parseInt(c.width*Math.random())%10)*(c.width/gridWidth)*2;
  var y=(parseInt(c.height*Math.random())%10)*(c.height/gridWidth)*2;
  var foot=new Init(x,y,gridWidth);
  foot.footInit();
  foots.push(foot);
 };
}
//画蛇的方法
function createSnack(){
 var t=this;
 //初始化方法
 t.dir='R';
 //随机产生一条蛇的方法
 t.addSnack=function(){
 console.log("产生一条蛇");
  var x=(parseInt(c.width*Math.random())%10)*(c.width/gridWidth)*2;
  var y=(parseInt(c.height*Math.random())%10)*(c.height/gridWidth)*2;
  var snack=new Init(x,y,gridWidth);
  snack.snackInit();
  snacks.push(snack);
  
 };
 
//  键盘监听
 document.οnkeydοwn=function(e){
  var code=e.keyCode;
  t.odir=t.dir;
  switch(code){
   case 37:
    t.dir='L';
    break;
   case 38:
    t.dir='U';
    break;
   case 39:
    t.dir='R';
    break;
   case 40:
    t.dir='D';
    break;
  }
  if(sfmove){
   t.move();
  }
  
 };
 var fals=true;
 //移动蛇
 t.move=function(){
//   t.snackSnack(t.dir);
//   var l=snacks.length;
//   alert(l);
  var newHead='';
  if(!fals){
   return;
  }
  //不能让蛇头超越框中
  if(t.dir=='R'){
   if(snacks[0].x+2*snacks[0].w>c.width){
    end();
    fals=false;
   }
   newHead=new Init(snacks[0].x+gridWidth,snacks[0].y,gridWidth);
   
  }
  if(t.dir=='U'){
   if(snacks[0].y-snacks[0].w<0){
    end();
    fals=false;
   }
   newHead=new Init(snacks[0].x,snacks[0].y-gridWidth,gridWidth);
   
  }
  if(t.dir=='L'){
   if(snacks[0].x-snacks[0].w<0){
    end();
    fals=false;
   }
   newHead=new Init(snacks[0].x-gridWidth,snacks[0].y,gridWidth);
  }
  if(t.dir=='D'){
   if(snacks[0].y+2*snacks[0].w>c.height){
    end();
    fals=false;
   }
   newHead=new Init(snacks[0].x,snacks[0].y+gridWidth,gridWidth);
  }
  
  //画蛇头
  newHead.snackInit();
  //将蛇头追加到数组中
  snacks.unshift(newHead);
  //静止反向跑
  if(newHead.x==snacks[1].x && newHead.y==snacks[1].y){
   t.dir=t.odir;
   return;
  }
  //清除掉蛇尾
  snacks[snacks.length-1].clear();
  snacks.pop();
  t.addSnackFoot(t.dir);
  
  
 };
 //增加蛇尾的方法
 t.addSnackFoot=function(dir){
  var fork=false;
  var fal=false;
  for(var j=0;j<snacks.length;j++){
   for(var i=0;i<foots.length;i++){
    if(foots[i]!=null){
     fal= foots[i].check(snacks[0]);
      if(fal){
       var snackfoot='';
       //如何蛇与食物碰撞了则增加蛇的长度
       if(snacks.length<2){
        if(dir=='R'){
         snackfoot=new Init(snacks[j].x-snacks.length*gridWidth,snacks[0].y,gridWidth);
        }
        if(dir=='L'){
         snackfoot=new Init(snacks[j].x+snacks.length*gridWidth,snacks[0].y,gridWidth);
        }
        if(dir=='U'){
         snackfoot=new Init(snacks[j].x,snacks[0].y+snacks.length*gridWidth,gridWidth);
        }
        if(dir=='D'){
         snackfoot=new Init(snacks[j].x,snacks[0].y-snacks.length*gridWidth,gridWidth);
        }
       }else{
        if(snacks[snacks.length-1].x<snacks[0].x){
         if(snacks[snacks.length-2].y==snacks[snacks.length-1].y){
          if(snacks[snacks.length-2].x>snacks[snacks.length-1].x){
           snackfoot=new Init(snacks[snacks.length-1].x-gridWidth,snacks[snacks.length-1].y,gridWidth);
          }
          if(snacks[snacks.length-2].x<snacks[snacks.length-1].x){
           snackfoot=new Init(snacks[snacks.length-1].x+gridWidth,snacks[snacks.length-1].y,gridWidth);
          }
         }
         if(snacks[snacks.length-2].y>snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[snacks.length-1].x,snacks[snacks.length-1].y-gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y<snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[snacks.length-1].x,snacks[snacks.length-1].y+gridWidth,gridWidth);
         }
         
        }
        if(snacks[snacks.length-1].x>snacks[0].x){
         if(snacks[snacks.length-2].y==snacks[snacks.length-1].y){
          if(snacks[snacks.length-2].x>snacks[snacks.length-1].x){
           snackfoot=new Init(snacks[snacks.length-1].x-gridWidth,snacks[snacks.length-1].y,gridWidth);
          }
          if(snacks[snacks.length-2].x<snacks[snacks.length-1].x){
           snackfoot=new Init(snacks[snacks.length-1].x+gridWidth,snacks[snacks.length-1].y,gridWidth);
          }
         }
         if(snacks[snacks.length-2].y>snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[snacks.length-1].x,snacks[snacks.length-1].y-gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y<snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[snacks.length-1].x,snacks[snacks.length-1].y+gridWidth,gridWidth);
         }
        }
        if(snacks[snacks.length-1].x==snacks[0].x && snacks[snacks.length-1].y>snacks[0].y){
         if(snacks[snacks.length-2].y>snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y-gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y<snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y+gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y==snacks[snacks.length-1].y ){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y+gridWidth,gridWidth);
//           if(snacks[snacks.length-2].x>snacks[snacks.length-1].x){
//            snackfoot=new Init(snacks[0].x-gridWidth,snacks[snacks.length-1].y,gridWidth);
//           }
//           if(snacks[snacks.length-2].x<snacks[snacks.length-1].x){
//            snackfoot=new Init(snacks[0].x+gridWidth,snacks[snacks.length-1].y,gridWidth);
//           }
         }
         
        }
        if(snacks[snacks.length-1].x==snacks[0].x && snacks[snacks.length-1].y<snacks[0].y){
         if(snacks[snacks.length-2].y>snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y-gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y<snacks[snacks.length-1].y){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y+gridWidth,gridWidth);
         }
         if(snacks[snacks.length-2].y==snacks[snacks.length-1].y ){
          snackfoot=new Init(snacks[0].x,snacks[snacks.length-1].y-gridWidth,gridWidth);
//           if(snacks[snacks.length-2].x>snacks[snacks.length-1].x){
//            snackfoot=new Init(snacks[0].x-gridWidth,snacks[snacks.length-1].y,gridWidth);
//           }
//           if(snacks[snacks.length-2].x<snacks[snacks.length-1].x){
//            snackfoot=new Init(snacks[0].x+gridWidth,snacks[snacks.length-1].y,gridWidth);
//           }
         }
        }
       }
       snackfoot.snackInit();
       snacks.push(snackfoot);
       fork=true;
       fal=false;
       
      }
    }
    if(fork){
     break;
    }
   }
   if(fork){
    break;
   }
  }
 };
 var dirs='';
 //如何蛇自己与自己碰撞了则减少一个长度
 t.snackSnack=function(dir){
  var xdir=dir;
  var ydir=dirs;
  dirs=dir;
  if((xdir=='R' && ydir=='L')||(xdir=='L' && ydir=='R')){
   end();
  }
  if((xdir=='U' && ydir=='D')||(xdir=='D' && ydir=='U')){
   end();
  }
 };
}
var time="";
//游戏开始的方法
function start(){
 //初始画布
 var c=document.getElementById("myCanvas");
 var ctx=c.getContext("2d");
  ctx.fillStyle='white';
  ctx.strokeStyle='red';
  ctx.fillRect(0,0,c.width,c.height);
  ctx.fillRect(0,0,c.width,c.height);
 
  sfmove=true;
  if(foots.length>=1){
   for(var i=0;i<foots.length;i++){
    foots[i].footInit();
   }
  }
   if(snacks.length>=1){
    for(var i=0;i<snacks.length;i++){
     snacks[i].snackInit();
    }
    
   }
  if(snacks.length<1){
   var snack=new createSnack();
   snack.addSnack();
  }
  
  
 var create=new createFoot();
//  create.addFont();
 time=window.setInterval(create.addFont, 2000);
 
}
//游戏结束的方法
function end(){
 var c=document.getElementById("myCanvas");
 var ctx=c.getContext("2d");
 ctx.font='bold 50px arial';
 ctx.fillStyle='red';
 ctx.fillText('GameOver!',50,200);
 foots=[];
 snacks=[];
 window.clearInterval(time);
}
//游戏暂停
function startEnd(){
 var c=document.getElementById("myCanvas");
 var ctx=c.getContext("2d");
 ctx.font='bold 50px arial';
 ctx.fillStyle='red';
 ctx.fillText('游戏暂停!',50,200);
 window.clearInterval(time);
 sfmove=false;
//  snacks.clear();
}
</script>
</body>
</html>